package com.xy.common.util;

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xiao.yi
 * @date 2023/9/28 14:18
 */
public class UserAgent {
    private static final Logger log = LoggerFactory.getLogger(UserAgent.class);
    private static final Pattern PATTERN_ANDROID = Pattern.compile("Android\\s([\\d\\.]+)");
    private static final Pattern PATTERN_IOS = Pattern.compile("(iPhone;|iPod;|iPad;)[\\s\\w]+OS (\\d+)");
    public static final String IPAD = "ipad";
    public static final String IPHONE = "iphone";
    public static final String IPOD = "ipod";
    public static final String MAC_OS = "mac os";
    public static final String ANDROID = "android";
    public static final String IOS = "ios";
    public static final String EDGE = "edge";
    public static final String FIREFOX = "firefox";
    public static final String IE = "ie";
    public static final String SAFARI = "safari";
    public static final String CHROME = "chrome";
    public static final String CRIOS = "crios";
    public static final String TRIDENT = "trident";
    public static final String OTHER = "other";
    public static final String DESKTOP = "desktop";
    public static final String MICRO_MESSENGER = "micromessenger";
    public static final String WECHAT = "wechat";
    public static final String WEIBO = "weibo";

    public UserAgent() {
    }

    public static boolean isWeixin(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        return StrUtil.isNotBlank(ua) ? ua.toLowerCase().contains("micromessenger") : false;
    }

    public static boolean isMobile(HttpServletRequest request) {
        UserDevice ud = getUserDevice(request);
        return ud.getMobile();
    }

    public static boolean isDesktop(HttpServletRequest request) {
        UserDevice ud = getUserDevice(request);
        return !ud.getMobile();
    }

    public static UserDevice getUserDevice(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        UserDevice ud = new UserDevice(ua);
        if (StrUtil.isBlank(ua)) {
            return ud;
        } else {
            String userEnv = null;
            String deviceVersion = null;
            ua = ua.toLowerCase();
            String deviceType;
            Matcher mat;
            String group;
            String[] ga;
            if (!includes(ud, ua, "ipad") && !includes(ud, ua, "iphone") && !includes(ud, ua, "ipod")) {
                if (includes(ud, ua, "mac os")) {
                    deviceType = "mac os";
                } else if (includes(ud, ua, "android")) {
                    deviceType = "android";
                    mat = PATTERN_ANDROID.matcher(ua);

                    while(mat.find()) {
                        group = mat.group();
                        ga = group.split("");
                        if (ga.length == 2) {
                            deviceVersion = ga[1];
                        }
                    }
                } else {
                    deviceType = "desktop";
                }
            } else {
                deviceType = "ios";
                mat = PATTERN_IOS.matcher(ua);

                while(mat.find()) {
                    group = mat.group();
                    ga = group.split(" ");
                    if (ga.length > 2) {
                        deviceVersion = ga[ga.length - 1];
                    }
                }
            }

            if (includes(ud, ua, "micromessenger")) {
                userEnv = "wechat";
            } else if (includes(ud, ua, "weibo")) {
                userEnv = "weibo";
            }

            boolean isMobile = includes(ud, ua, "android") || includes(ud, ua, "iphone") || includes(ud, ua, "ipod");
            ud.setDeviceType(deviceType);
            ud.setDeviceVersion(deviceVersion);
            ud.setMobile(isMobile);
            ud.setUserEnv(userEnv);
            if (ua.contains("edge")) {
                ud.setBrowser("edge");
            } else if (ua.contains("firefox")) {
                ud.setBrowser("firefox");
            } else if (ua.contains("trident")) {
                ud.setBrowser("ie");
            } else if (ua.contains("crios")) {
                ud.setBrowser("crios");
            } else if (ua.contains("safari") && !ua.contains("chrome")) {
                ud.setBrowser("safari");
            } else if (ua.contains("chrome")) {
                ud.setBrowser("chrome");
            } else {
                ud.setBrowser("other");
            }

            log.debug(ud.toString());
            return ud;
        }
    }

    private static boolean includes(UserDevice ud, String ua, String str) {
        if (StrUtil.isNotBlank(ua) && ua.toLowerCase().contains(str.toLowerCase())) {
            ud.setDevice(str.toLowerCase());
            return true;
        } else {
            return false;
        }
    }
}
